/*
 * Copyright 2018 Dash Core Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This file was generated by SWIG (http://www.swig.org) and modified.
 * Version 3.0.12
 */

package org.dashj.bls;

import com.google.common.base.Preconditions;

import java.util.Arrays;

public class AggregationInfo {
  private transient long cPointer;
  protected transient boolean owner;

  protected AggregationInfo(long cPtr, boolean cMemoryOwn) {
    Preconditions.checkArgument(cPtr != 0);
    owner = cMemoryOwn;
    cPointer = cPtr;
  }

  protected static long getCPtr(AggregationInfo obj) {
    return (obj == null) ? 0 : obj.cPointer;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (cPointer != 0) {
      if (owner) {
        owner = false;
        JNI.delete_AggregationInfo(cPointer);
      }
      cPointer = 0;
    }
  }

  public static AggregationInfo FromMsgHash(PublicKey pk, byte[] messageHash) {
    Preconditions.checkNotNull(pk);
    Preconditions.checkNotNull(messageHash);
    return new AggregationInfo(JNI.AggregationInfo_FromMsgHash(PublicKey.getCPtr(pk), pk, messageHash), true);
  }

  public static AggregationInfo FromMsg(PublicKey pk, byte[] message, long len) {
    Preconditions.checkNotNull(pk);
    Preconditions.checkNotNull(message);
    Preconditions.checkState(message.length >= len);
    return new AggregationInfo(JNI.AggregationInfo_FromMsg(PublicKey.getCPtr(pk), pk, message, len), true);
  }

  public static AggregationInfo FromVectors(PublicKeyVector pubKeys, MessageHashVector messageHashes, BigIntegerVector exponents) {
    Preconditions.checkNotNull(pubKeys);
    Preconditions.checkNotNull(messageHashes);
    Preconditions.checkNotNull(exponents);
    Preconditions.checkArgument(pubKeys.size() == messageHashes.size(), "Invalid input, all std::vectors must have the same length (" + pubKeys.size() + " != " + messageHashes.size() + ")");
    return new AggregationInfo(JNI.AggregationInfo_FromVectors(PublicKeyVector.getCPtr(pubKeys), pubKeys, MessageHashVector.getCPtr(messageHashes), messageHashes, BigIntegerVector.getCPtr(exponents), exponents), true);
  }

  public static AggregationInfo MergeInfos(AggregationInfoVector infos) {
    Preconditions.checkNotNull(infos);
    return new AggregationInfo(JNI.AggregationInfo_MergeInfos(AggregationInfoVector.getCPtr(infos)), true);
  }

  public AggregationInfo(AggregationInfo info) {
    this(JNI.new_AggregationInfo__SWIG_0(AggregationInfo.getCPtr(info), info), true);
  }

  public void RemoveEntries(MessageHashVector messages, PublicKeyVector pubKeys) {
    Preconditions.checkNotNull(messages);
    Preconditions.checkNotNull(pubKeys);
    Preconditions.checkArgument(messages.size() != pubKeys.size(), "Invalid entries");
    JNI.AggregationInfo_RemoveEntries(cPointer, this, MessageHashVector.getCPtr(messages), messages, PublicKeyVector.getCPtr(pubKeys), pubKeys);
  }

  public void GetExponent(SWIGTYPE_p_bn_t result, byte[] messageHash, PublicKey pubkey) {
    JNI.AggregationInfo_GetExponent(cPointer, this, SWIGTYPE_p_bn_t.getCPtr(result), messageHash, PublicKey.getCPtr(pubkey), pubkey);
  }

  public PublicKeyVector GetPubKeys() {
    return new PublicKeyVector(JNI.AggregationInfo_GetPubKeys(cPointer, this), true);
  }

  public MessageHashVector GetMessageHashes() {
    return new MessageHashVector(JNI.AggregationInfo_GetMessageHashes(cPointer, this), true);
  }

  public boolean Empty() {
    return JNI.AggregationInfo_Empty(cPointer, this);
  }

  public AggregationInfo() {
    this(JNI.new_AggregationInfo__SWIG_1(), true);
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null || !(obj instanceof AggregationInfo))
      return false;

    AggregationInfo aggInfo = (AggregationInfo)obj;
    MessageHashVector otherMessageHashes = aggInfo.GetMessageHashes();
    PublicKeyVector otherPublicKeys = aggInfo.GetPubKeys();

    return JNI.AggregationInfo_Equals(cPointer, this, AggregationInfo.getCPtr(aggInfo), aggInfo);
  }

  @Override
  public String toString() {
    return "AggregationInfo(PublicKeys: " + GetPubKeys().size() + ", MessageHashes: " + GetMessageHashes().size() + ")";
  }

}
